﻿namespace FlyRemote.Base
{
    /// <summary>
    /// 取一个 4字节, 8字节 , 首个非0字节 , 及其偏移 
    /// </summary>
    public struct ByteHeader
    {
        /// <summary>
        /// 首个非0 字节 
        /// </summary>
        public byte header;

        /// <summary>
        /// 偏移量
        /// </summary>
        public byte offset;



        /// <summary>
        /// 从 8 字节 创建
        /// </summary>
        public ByteHeader(ulong addr)
        {
            header = getHeader(addr, out offset);
        }


        /// <summary>
        /// 从 4 字节 创建
        /// </summary>
        public ByteHeader(uint addr)
        {
            header = getHeader(addr, out offset);
        }

        /// <summary>
        /// 将首字节 和偏移 , 合并为一个数据 , 方便判断 
        /// </summary>
        public int Info
        {
            get => (int)(header << 0x10) + offset;

            set
            {
                header = (byte)(value >> 0x10);
                offset = (byte)(value & 0xff);
            }
        }
        public ulong Value
        {
            get => (ulong)header << (8 * offset);
        }

        /// <summary>
        /// 取从高位起 第一个非0的字节，且带有该字节的位置
        /// </summary>
        public static byte getHeader(ulong addr, out byte offset)
        {

            byte st = 0;
            offset = 0;

            for (byte i = 7; i > 0; i--)
            {
                if ((addr & ((ulong)0xFF << (8 * i))) > 0)
                {
                    st = (byte)(addr >> (8 * i));
                    offset = i;
                    break;
                }
            }

            return st;
        }

        /// <summary>
        /// 取从高位起 第一个非0的字节，且带有该字节的位置
        /// </summary>
        public static byte getHeader(uint addr, out byte offset)
        {

            byte st = 0;
            offset = 0;

            // 地址是一个  0xAA?????? 形式 
            for (byte i = 3; i > 0; i--)
            {
                if ((addr & (0xFF << (8 * i))) > 0)
                {
                    st = (byte)(addr >> (8 * i));
                    offset = i;
                    break;
                }
            }


            return st;
        }

    }


    /// <summary>
    /// 取一个 4字节, 8字节 , 前两个非0字节 , 及其偏移 
    /// </summary>
    public struct ByteHeader2
    {
        /// <summary>
        /// 首个非0 字节 
        /// </summary>
        public short header;

        /// <summary>
        /// 偏移量
        /// </summary>
        public byte offset;


        /// <summary>
        /// 从 8 字节 创建
        /// </summary>
        public ByteHeader2(ulong addr)
        {
            header = getHeader2(addr, out offset);
        }


        /// <summary>
        /// 从 8 字节 创建
        /// </summary>
        public ByteHeader2(uint addr)
        {
            header = getHeader2(addr, out offset);
        }


        /// <summary>
        ///  从高位起 前两个非0的字节， 如 0x0000560012345678  => 0x5600 
        /// </summary>
        public static short getHeader2(ulong address, out byte offset)
        {

            offset = 0;

            for (byte i = 6; i > 0; i--)
            {
                ulong l = address >> 8 * i;
                if ((l & 0xFF00) > 0)
                {

                    offset = i;
                    return (short)l;
                }

            }
            return 0;


        }


        /// <summary>
        ///  从高位起 前两个非0的字节， 如 0x00560012  => 0x5600 
        /// </summary>
        public static short getHeader2(uint address, out byte offset)
        {

            offset = 0;

            for (byte i = 2; i > 0; i--)
            {
                uint l = address >> 8 * i;
                if ((l & 0xFF00) > 0)
                {

                    offset = i;
                    return (short)l;
                }

            }
            return 0;


        }


    }

    static class AddressExt
    {






        /// <summary>
        /// 取从高位起 第一个非0的字节，且带有该字节的位置
        /// </summary>
        public static short getHeaderOff(this ulong addr)
        {

            short st = 0;

            for (int i = 7; i > 0; i--)
            {
                if ((addr & ((ulong)0xFF << (8 * i))) > 0)
                {
                    st = (short)(addr >> (8 * i));
                    st |= (short)((i) << 8);
                    break;
                }
            }

            return st;
        }

        /// <summary>
        /// 取从高位起 第一个非0的字节，且带有该字节的位置
        /// </summary>
        public static short getHeaderOff(this uint addr)
        {

            short st = 0;
            // 地址是一个  0xAA?????? 形式 
            for (int i = 3; i > 0; i--)
            {
                if ((addr & (0xFF << (8 * i))) > 0)
                {
                    st = (short)(addr >> (8 * i));
                    st |= (short)((i) << 8);
                    break;
                }
            }


            return st;
        }

    }
}
